<?php
// 变量创建赋值，内存变化 demo1
	demo1();
	echo '<hr>';
	function demo1(){
		// 使用memory_get_usage()查看内存使用情况
		$a = range(1, 100); // 在内存中为$a开辟变量空间
		var_dump(memory_get_usage());
		$b = $a; // $b指向$a的变量空间
		var_dump(memory_get_usage());
		$a = range(1, 100); // 在内存为$a开辟新的空间，$a指向新空间，$b指向不变
		var_dump(memory_get_usage());
	}
	
// 引用内存变化 demo2
	demo2();
	echo '<hr>';
	function demo2(){
		$a = range(1, 100);
		var_dump(memory_get_usage());
		$b = &$a; // $b地址永久指向$a
		var_dump(memory_get_usage());
		$a = range(1, 100); //修改$a或$b,地址空间内值改变
		var_dump(memory_get_usage());
	}
	
// zval结构体 
	// 使用xdebug_debug_zval()查看变量zval结构体，需要安装xdebug扩展
	// 变量 demo3
		demo3();
		echo '<hr>';
		function demo3(){
			$a = range(0, 3);
			xdebug_debug_zval('a');
				// a:
				// 	refcount = 1, 有一个变量指向内存空间
				// 	is_ref = 0， 不是引用
			$b = $a;
			xdebug_debug_zval('a');
				// a:
				// 	refcount = 2, 有一个变量指向内存空间
				// 	is_ref = 0， 不是引用
			$a = range(0, 3);
			xdebug_debug_zval('a');
				// a:
				// 	refcount = 1, 有一个变量指向内存空间
				// 	is_ref = 0， 不是引用
		}
		
	// 引用 demo4
		demo4();
		echo '<hr>';
		function demo4(){
			$a = range(0, 3);
			xdebug_debug_zval('a');
				// a:
				// 	refcount = 1, 有一个变量指向内存空间
				// 	is_ref = 0， 不是引用
			$b = &$a;
			xdebug_debug_zval('a');
				// a:
				// 	refcount = 2, 有一个变量指向内存空间
				// 	is_ref = 1， 是引用
			$a = range(0, 3);
			xdebug_debug_zval('a');
				// a:
				// 	refcount = 2, 有一个变量指向内存空间
				// 	is_ref = 1， 是引用
		}
		
// 对象 demo5
	demo5();
	echo '<hr>';
	function demo5(){
		class Person{
			public $name = "zhangsan";
		}
		$p1 = new Person;
		xdebug_debug_zval('p1');
		$p2 = $p1;
		xdebug_debug_zval('p1');
		$p2->name = "lisi";
		xdebug_debug_zval('p1');
	}

// 引用 example1
	example1();
	echo '<hr>';
	function example1(){
		$data = ['a','b','c'];
		foreach($data as $key => $value){
			$value = &$data[$key];
			var_dump($data);
			// [a,b,c]
			// [b,b,c]
			// [b,c,c]
		}
		var_dump($data);
		// [b,c,c]
	}

// 字符串 demo6
	demo6();
	echo '<hr>';
	function demo6(){
		$a = 'zx';
		$str = 'a b c d e $a f g';
		var_dump($str); // a b c d e $a f g
		$str = "a b c d e '{$a}' f g";
		var_dump($str); // a b c d e 'zx' f g
		$str = "a b c d e &$a& f g";
		var_dump($str); // a b c d e &zx& f g
		// heredoc
		$str = <<< EOF
		a$a
EOF;
		var_dump($str); // azx
		// newdoc
		$str = <<< 'EOF'
		a$a
EOF;
		var_dump($str); // a$a
	}

// 运算符 example2
	example2();
	echo '<hr>';
	function example2(){
		$a = 0;
		$b = 0;
		if($a = 3 > 0 || $b = 3 > 0){ // $a = ((3 > 0) || $b = (3 > 0))
			var_dump($a);
			var_dump($b);
			$a++; // $a = true; $a++ = true;
			$b++; // $b = 0; $b++ = 1;
			echo $a.'<br>';
			echo $b.'<br>';
		}
	}

// 自定义函数及内部函数 example3
	example3();
	echo '<hr>';
	function example3(){
		$conut = 5;
		function get_count(){
			static $conut;
			return $conut++;
		}
		echo $conut; // 5
		++$conut; // 6
		echo get_count(); // NULL NULL不会输出
		echo get_count(); // 1
		// 51
	}

// demo7
	demo7();
	echo '<hr>';
	function demo7(){
		function &myFunc(){
			static $b = 10;
			return $b;
		}
		echo myFunc(); // 10
		$a = &myFunc(); 
		$a = 100;
		echo myFunc(); // 100
	}

// 自定义函数及内部函数 example4
	$var1 = 5;
	$var2 = 10;
	function foo(&$my_var){
		global $var1;
		$var1 += 2;
		$var2 = 4;
		$my_var +=3;
		return $var2;
	}
	$my_var = 5;
	echo foo($my_var).'<br>'; // 4
	echo $my_var.'<br>'; // 8
	echo $var1; // 7
	echo $var2; // 10
	$bar = 'foo';
	$my_var = 10;
	echo $bar($my_var).'<br>'; // 4

	echo '<hr>';

// 正则表达式 demo8
	$str = '中文';
	// utf-8
	$pattern = '/[\x{4e00}-\x{9fa5}]+/u';
	// gb2312
	// $pattern = '/['.chr(0xb0).'-'.chr(0xf7).']['.chr(0xa1).'-'.chr(0xfe).']/';
	preg_match($pattern, $str, $match);
	var_dump($match);

// demo9
	// 以139开头的11位手机号码的正则表达式
	// 13966666666
	$str = '13966666666';
	$pattern = '/^139\d{8}$/';
	preg_match($pattern, $str, $match);
	var_dump($match);

// demo10
	// 匹配所有img标签中src的值
	$str = '<img alt="alt文字" id="id" src="id.jpg" />';
	$pattern = '/<img.*?src="(.*?)".*?\/?>/i';
	preg_match($pattern, $str, $match);
	var_dump($match);

// 文件及目录 example1
	// 在文件开头不断写入hello world
	$file = './hello.txt';
	$handle = fopen($file,'r');
	$content = fread($handle, filesize($file));
	$content = 'Hello World '.$content;
	fclose($handle);
	$handle = fopen($file, 'w');
	fwrite($handle, $content);
	fclose($handle);

// 文件及目录 example2
	// 通过php函数的方式对目录进行遍历
	$dir = './dir';

	// 打开目录
	// 读取目录当中的文件
	// 如果文件类型是目录，继续打开目录
	// 读取子目录的文件
	// 如果文件类型是文件，输出文件名称
	// 关闭目录
	function loopDir($dir){
		$handle = opendir($dir);
		while(false!==($file = readdir($handle))){
			if($file != '.' && $file != '..'){
				echo $file."\n";
				if(filetype($dir.'/'.$file) == 'dir'){
					loopDir($dir.'/'.$file);
				}
			}
		}
	}

	loopDir($dir);


?>